/*
 * @(#)XfslSettingsDialog.java        1.0 2000/05/09
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

package xfuzzy.xfsl.view;

import xfuzzy.lang.*;
import xfuzzy.util.*;
import xfuzzy.xfsl.model.XfslSetting;
import xfuzzy.xfsl.view.listener.*;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.util.Vector;

/**
 * Ventana de selecci�n de par�metros a ajustar
 * 
 * @author Francisco Jos� Moreno Velo
 *
 */
public class XfslSettingsDialog extends JDialog implements ListSelectionListener {

	//----------------------------------------------------------------------------//
	//                            COSTANTES PRIVADAS                              //
	//----------------------------------------------------------------------------//

	/**
	 * C�digo asociado a la clase serializable
	 */
	private static final long serialVersionUID = 95505666603070L;

	//----------------------------------------------------------------------------//
	//                            MIEMBROS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Ventana principal de la herramienta xfsl
	 */
	private Xfsl xfsl;
	
	/**
	 * Listas
	 */
	private JList list[] = new JList[4];
	
	/**
	 * Tipos de variables a seleccionar en la primera lista
	 */
	private Type type[];
	
	/**
	 * Tipo seleccionado en la primera lista
	 */
	private Type typesel;
	
	/**
	 * Funci�n seleccionada en la segunda lista
	 */
	private ParametricFunction mfsel;
	
	/**
	 * Vector de elecciones de par�metros
	 */
	private Vector<XfslSetting> vsett;

	//----------------------------------------------------------------------------//
	//                                CONSTRUCTOR                                 //
	//----------------------------------------------------------------------------//

	/**
	 * Constructor
	 */
	public XfslSettingsDialog(Xfsl xfsl) {
		super(xfsl, "Xfsl", true);
		this.xfsl = xfsl;
		this.type = xfsl.getSpec().getTypes();
		build();
		data0();
	}

	//----------------------------------------------------------------------------//
	//                             M�TODOS P�BLICOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Interfaz ListSelectionListener
	 */
	public void valueChanged(ListSelectionEvent e) {
		if(e.getSource() == list[0]) data1();
		if(e.getSource() == list[1]) data2();
	}

	/**
	 * Acci�n de crear una selecci�n de habilitaci�n
	 */
	public void actionEnable() {
		String selected = (String) list[2].getSelectedValue();
		if(selected == null) return;
		int param;
		try { param = Integer.parseInt(selected); }
		catch(Exception ex) { param = XfslSetting.NOT_SELECTED; }
		vsett.addElement(new XfslSetting(typesel,mfsel,param,true));
		list[3].setListData(vsett);
	}

	/**
	 * Acci�n de crear una selecci�n de deshabilitaci�n
	 */
	public void actionDisable() {
		String selected = (String) list[2].getSelectedValue();
		if(selected == null) return;
		int param;
		try { param = Integer.parseInt(selected); }
		catch(Exception ex) { param = XfslSetting.NOT_SELECTED; }
		vsett.addElement(new XfslSetting(typesel,mfsel,param,false));
		list[3].setListData(vsett);
	}

	/**
	 * Acci�n de eliminar una selecci�n
	 */
	public void actionDelete() {
		XfslSetting selected = (XfslSetting) list[3].getSelectedValue();
		if(selected == null) return;
		vsett.removeElement(selected);
		list[3].setListData(vsett);
	}

	/**
	 * Acci�n de aceptar el conjunto de selecciones
	 */
	public void actionSet() {
		Object[] obj = vsett.toArray();
		XfslSetting setting[] = new XfslSetting[obj.length];
		for(int i=0; i<obj.length; i++) setting[i] = (XfslSetting) obj[i];
		xfsl.getConfig().setSettings(setting);
		setVisible(false);
	}

	/**
	 * Acci�n de rechazar el conjunto de selecciones
	 */
	public void actionUnset() {
		xfsl.getConfig().setSettings(new XfslSetting[0]);
		setVisible(false);
	}
	
	//----------------------------------------------------------------------------//
	//                             M�TODOS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Construye la ventana
	 */
	private void build() {
		XfslSettingsActionListener listener = new XfslSettingsActionListener(this);
		
		String llabel[] = { "Type", "Family/Membership Function", "Parameter" };
		Box hbox = new Box(BoxLayout.X_AXIS);
		for(int i=0; i<3; i++) {
			list[i] = new JList();
			list[i].setBackground(XConstants.textbackground);
			JScrollPane pane = new JScrollPane(list[i]);
			Dimension prefsize = pane.getPreferredSize();
			pane.setPreferredSize(new Dimension(150,prefsize.height));
			Box box = new Box(BoxLayout.Y_AXIS);
			box.add(new XLabel(llabel[i]));
			box.add(pane);
			hbox.add(box);
		}
		list[0].addListSelectionListener(this);
		list[1].addListSelectionListener(this);
		list[3] = new JList();
		list[3].setBackground(XConstants.textbackground);

		String label1[] = { "Enable", "Disable", "Delete" };
		String label2[] = { "Set", "Unset", "Cancel" };
		XCommandForm form1 = new XCommandForm(label1,label1,listener);
		XCommandForm form2 = new XCommandForm(label2,label2,listener);
		form1.setCommandWidth(140);
		form2.setCommandWidth(140);

		Container content = getContentPane();
		content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS));
		content.add(new XLabel("Learning Settings"));
		content.add(hbox);
		content.add(new XLabel(" "));
		content.add(new JScrollPane(list[3]));
		content.add(form1);
		content.add(form2);

		Point loc = xfsl.getLocationOnScreen();
		loc.x += 40; loc.y += 200;
		setLocation(loc);
		pack();
	}

	/**
	 * Actualiza el contenido de la lista de tipos
	 */
	private void data0() {
		Vector<String> v = new Vector<String>();
		v.add("ANY");
		for(int i=0; i<type.length; i++) v.add(type[i].getName());
		list[0].setListData(v);

		vsett = new Vector<XfslSetting>();
		XfslSetting[] setting = xfsl.getConfig().getSettings();
		for(int i=0; i<setting.length; i++) vsett.addElement(setting[i]);
		list[3].setListData(vsett);
	}

	/**
	 * Actualiza el contenido de la lista de MFs
	 */
	private void data1() {
		String selected = (String) list[0].getSelectedValue();
		if(selected == null) return;
		if(selected.equals("ANY")) typesel = null;
		else try {
			int index;
			for(index=0; !type[index].equals(selected); index++);
			typesel = type[index];
		} catch(Exception ex) { typesel = null; }

		Vector<String> v = new Vector<String>();
		v.add("ANY");
		if(typesel != null) {
			Family[] fam = typesel.getFamilies();
			for(int j=0; j<fam.length; j++) v.add(fam[j].toString());
			ParamMemFunc mf[] = typesel.getParamMembershipFunctions();
			for(int j=0; j<mf.length; j++) v.add(mf[j].toString());
		}
		mfsel = null;
		list[1].setListData(v);
		list[2].setListData(new Vector<String>());
	}

	/**
	 * Actualiza el contenido de la lista de parametros
	 */
	private void data2() {
		String selected = (String) list[1].getSelectedValue();
		if(selected == null) return;
		if(selected.equals("ANY")) mfsel = null;
		else {
			Family[] fam = typesel.getFamilies();
			for(int i=0; i<fam.length; i++) if(fam[i].equals(selected)) mfsel = fam[i];
			ParamMemFunc mf[] = typesel.getParamMembershipFunctions();
			for(int i=0; i<mf.length; i++) if(mf[i].equals(selected)) mfsel = mf[i];
		}

		Vector<String> v = new Vector<String>();
		v.add("ANY");
		if(mfsel == null) {
			int max = 0;
			if(typesel == null) max = 4;
			else {
				Family[] fam= typesel.getFamilies();
				for(int i=0; i<fam.length; i++) max = Math.max(max,fam[i].get().length);
				ParamMemFunc mf[] = typesel.getParamMembershipFunctions();
				for(int i=0; i<mf.length; i++) max = Math.max(max,mf[i].get().length);
			}
			for(int i=1; i<=max; i++) v.add(""+i);
		}
		else for(int i=1, n=mfsel.get().length; i<=n; i++) v.add(""+i);
		list[2].setListData(v);
	}

}

